/**
 * 埋点管理器 - 负责初始化、上传、清理等操作
 * @author lhx
 */

import { store } from '../../store';
import { 
  loadTrackingDataLhx,
  addToUploadQueue,
  setUploadingStatus,
  markEventsAsUploaded,
  updateLastUploadTime,
  incrementRetryCount,
  removeUploadedEvents,
  initSession,
  selectUnuploadedEvents,
  selectTrackingConfig,
  selectIsUploading
} from '../../store/slices/trackingSliceLhx';
import TrackingStorageLhx from '../storage/trackingStorageLhx';
import TrackingServiceLhx from '../services/trackingServiceLhx';
import { TrackingEvent } from '../types/trackingTypes';

class TrackingManagerLhx {
  private static instance: TrackingManagerLhx;
  private uploadTimer: NodeJS.Timeout | null = null;
  private cleanupTimer: NodeJS.Timeout | null = null;
  private isInitialized = false;

  private constructor() {}

  public static getInstance(): TrackingManagerLhx {
    if (!TrackingManagerLhx.instance) {
      TrackingManagerLhx.instance = new TrackingManagerLhx();
    }
    return TrackingManagerLhx.instance;
  }

  /**
   * 初始化埋点管理器
   */
  public async initialize(userId?: string): Promise<void> {
    if (this.isInitialized) {
      console.log('[TrackingManagerLhx] Already initialized');
      return;
    }

    try {
      console.log('[TrackingManagerLhx] Initializing...');

      // 初始化服务
      const trackingService = TrackingServiceLhx.getInstance();
      
      // 设置用户ID并创建新会话
      if (userId) {
        trackingService.setUserId(userId);
      }
      
      const sessionId = trackingService.renewSession(userId);

      // 初始化Redux中的会话信息
      store.dispatch(initSession({ sessionId, userId }));

      // 从本地存储加载数据
      await store.dispatch(loadTrackingDataLhx());

      // 启动定时上传
      this.startPeriodicUpload();

      // 启动定时清理
      this.startPeriodicCleanup();

      this.isInitialized = true;
      console.log('[TrackingManagerLhx] Initialization completed');

    } catch (error) {
      console.error('[TrackingManagerLhx] Initialization failed:', error);
      throw error;
    }
  }

  /**
   * 设置用户ID
   */
  public setUserId(userId: string): void {
    const trackingService = TrackingServiceLhx.getInstance();
    trackingService.setUserId(userId);
    
    // 创建新会话
    const sessionId = trackingService.renewSession(userId);
    store.dispatch(initSession({ sessionId, userId }));
  }

  /**
   * 手动触发上传
   */
  public async uploadEvents(): Promise<boolean> {
    const state = store.getState();
    const config = selectTrackingConfig(state);
    const isUploading = selectIsUploading(state);

    // 检查是否正在上传
    if (isUploading) {
      console.log('[TrackingManagerLhx] Upload already in progress');
      return false;
    }

    // 检查是否启用
    if (!config.enabled) {
      console.log('[TrackingManagerLhx] Tracking disabled, skipping upload');
      return false;
    }

    try {
      store.dispatch(setUploadingStatus(true));

      // 获取未上传的事件
      const unuploadedEvents = selectUnuploadedEvents(state);

      if (unuploadedEvents.length === 0) {
        console.log('[TrackingManagerLhx] No events to upload');
        return true;
      }

      console.log(`[TrackingManagerLhx] Uploading ${unuploadedEvents.length} events`);

      // 分批上传
      const batchSize = config.batchSize;
      const batches = this.createBatches(unuploadedEvents, batchSize);

      for (const batch of batches) {
        try {
          const success = await this.uploadBatch(batch);
          if (success) {
            // 标记为已上传
            const eventIds = batch.map(event => event.id);
            store.dispatch(markEventsAsUploaded(eventIds));
            
            // 更新本地存储
            await TrackingStorageLhx.markEventsAsUploaded(eventIds);
          } else {
            // 增加重试次数
            const eventIds = batch.map(event => event.id);
            store.dispatch(incrementRetryCount(eventIds));
          }
        } catch (error) {
          console.error('[TrackingManagerLhx] Batch upload failed:', error);
          
          // 增加重试次数
          const eventIds = batch.map(event => event.id);
          store.dispatch(incrementRetryCount(eventIds));
        }
      }

      // 更新最后上传时间
      store.dispatch(updateLastUploadTime());

      return true;

    } catch (error) {
      console.error('[TrackingManagerLhx] Upload failed:', error);
      return false;
    } finally {
      store.dispatch(setUploadingStatus(false));
    }
  }

  /**
   * 强制上传高优先级事件
   */
  public async uploadHighPriorityEvents(): Promise<boolean> {
    const state = store.getState();
    const unuploadedEvents = selectUnuploadedEvents(state);
    
    // 过滤高优先级事件
    const highPriorityEvents = unuploadedEvents.filter(
      event => event.priority === 'high'
    );

    if (highPriorityEvents.length === 0) {
      return true;
    }

    console.log(`[TrackingManagerLhx] Uploading ${highPriorityEvents.length} high priority events`);

    try {
      const success = await this.uploadBatch(highPriorityEvents);
      if (success) {
        const eventIds = highPriorityEvents.map(event => event.id);
        store.dispatch(markEventsAsUploaded(eventIds));
        await TrackingStorageLhx.markEventsAsUploaded(eventIds);
      }
      return success;
    } catch (error) {
      console.error('[TrackingManagerLhx] High priority upload failed:', error);
      return false;
    }
  }

  /**
   * 清理已上传的事件
   */
  public async cleanupUploadedEvents(): Promise<void> {
    try {
      // 从Redux中移除已上传事件
      store.dispatch(removeUploadedEvents());
      
      // 从本地存储中移除已上传事件
      await TrackingStorageLhx.removeUploadedEvents();
      
      console.log('[TrackingManagerLhx] Cleanup completed');
    } catch (error) {
      console.error('[TrackingManagerLhx] Cleanup failed:', error);
    }
  }

  /**
   * 获取统计信息
   */
  public async getStatistics(): Promise<{
    memoryEvents: number;
    storageEvents: number;
    unuploadedEvents: number;
    storageSize: number;
    lastUploadTime: number;
  }> {
    const state = store.getState();
    const trackingState = state.trackingLhx || {};
    
    const storageStats = await TrackingStorageLhx.getStorageStats();
    
    return {
      memoryEvents: trackingState.events?.length || 0,
      storageEvents: storageStats.totalEvents,
      unuploadedEvents: storageStats.unuploadedEvents,
      storageSize: storageStats.storageSize,
      lastUploadTime: trackingState.lastUploadTime || 0
    };
  }

  /**
   * 停止管理器
   */
  public stop(): void {
    if (this.uploadTimer) {
      clearInterval(this.uploadTimer);
      this.uploadTimer = null;
    }

    if (this.cleanupTimer) {
      clearInterval(this.cleanupTimer);
      this.cleanupTimer = null;
    }

    this.isInitialized = false;
    console.log('[TrackingManagerLhx] Stopped');
  }

  /**
   * 重置管理器（清除所有数据）
   */
  public async reset(): Promise<void> {
    this.stop();
    
    // 清除Redux数据
    store.dispatch({ type: 'trackingLhx/clearAllData' });
    
    // 清除本地存储
    await TrackingStorageLhx.clearStorage();
    
    console.log('[TrackingManagerLhx] Reset completed');
  }

  // 私有方法

  /**
   * 启动定时上传
   */
  private startPeriodicUpload(): void {
    const state = store.getState();
    const config = selectTrackingConfig(state);

    if (this.uploadTimer) {
      clearInterval(this.uploadTimer);
    }

    this.uploadTimer = setInterval(() => {
      this.uploadEvents().catch(error => {
        console.error('[TrackingManagerLhx] Periodic upload failed:', error);
      });
    }, config.uploadInterval);

    console.log(`[TrackingManagerLhx] Periodic upload started (${config.uploadInterval}ms)`);
  }

  /**
   * 启动定时清理
   */
  private startPeriodicCleanup(): void {
    if (this.cleanupTimer) {
      clearInterval(this.cleanupTimer);
    }

    // 每小时清理一次
    this.cleanupTimer = setInterval(() => {
      this.cleanupUploadedEvents().catch(error => {
        console.error('[TrackingManagerLhx] Periodic cleanup failed:', error);
      });
    }, 60 * 60 * 1000);

    console.log('[TrackingManagerLhx] Periodic cleanup started');
  }

  /**
   * 创建上传批次
   */
  private createBatches<T>(items: T[], batchSize: number): T[][] {
    const batches: T[][] = [];
    for (let i = 0; i < items.length; i += batchSize) {
      batches.push(items.slice(i, i + batchSize));
    }
    return batches;
  }

  /**
   * 上传一个批次的事件
   */
  private async uploadBatch(events: TrackingEvent[]): Promise<boolean> {
    try {
      // 这里应该调用实际的API接口
      // 现在使用模拟的上传逻辑
      const response = await this.mockUploadAPI(events);
      
      if (response.success) {
        console.log(`[TrackingManagerLhx] Batch uploaded successfully: ${events.length} events`);
        return true;
      } else {
        console.warn('[TrackingManagerLhx] Batch upload failed:', response.error);
        return false;
      }
    } catch (error) {
      console.error('[TrackingManagerLhx] Upload batch error:', error);
      return false;
    }
  }

  /**
   * 模拟上传API（实际项目中应该替换为真实的API调用）
   */
  private async mockUploadAPI(events: TrackingEvent[]): Promise<{
    success: boolean;
    error?: string;
  }> {
    return new Promise((resolve) => {
      // 模拟网络延迟
      setTimeout(() => {
        // 模拟90%的成功率
        const success = Math.random() > 0.1;
        
        if (success) {
          resolve({ success: true });
        } else {
          resolve({ 
            success: false, 
            error: 'Network error or server unavailable' 
          });
        }
      }, 1000 + Math.random() * 2000); // 1-3秒延迟
    });
  }
}

export default TrackingManagerLhx;